package com.yht.redbook.data.align.job;

import cn.hutool.core.collection.CollUtil;
import com.xxl.job.core.context.XxlJobHelper;
import com.xxl.job.core.handler.annotation.XxlJob;
import com.yht.redbook.data.align.constant.RedisKeyConstants;
import com.yht.redbook.data.align.constant.TableConstants;
import com.yht.redbook.data.align.domain.mapper.DeleteMapper;
import com.yht.redbook.data.align.domain.mapper.SelectRecordMapper;
import com.yht.redbook.data.align.domain.mapper.UpdateRecordMapper;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;

import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.util.List;

@Component
@Slf4j
public class NoteCollectCountShardingXxlJob {

    @Resource
    private SelectRecordMapper selectRecordMapper;

    @Resource
    private UpdateRecordMapper updateRecordMapper;

    @Resource
    private RedisTemplate<String, Object> redisTemplate;

    @Resource
    private DeleteMapper deleteMapper;

    @XxlJob("noteCollectCountShardingJobHandler")
    public void noteCollectCountShardingJobHandler() {
        // 获取分片参数
        // 分片序号
        int shardIndex = XxlJobHelper.getShardIndex();
        // 分片总数
        int shardTotal = XxlJobHelper.getShardTotal();

        XxlJobHelper.log("=============> 开始定时分片广播任务：对当日发生变更的笔记收藏数进行对齐");
        XxlJobHelper.log("分片参数：当前分片序号 = {}，总分片数 = {}", shardIndex, shardTotal);

        log.info("分片参数：当前分片序号 = {}，总分片数 = {}", shardIndex, shardTotal);

        // 1.分批次查询 t_data_align_note_collect_count_temp_日期_分片序号，如一批次查询 1000 条，直到全部查询完成
        String date = LocalDate.now().minusDays(1).format(DateTimeFormatter.ofPattern("yyyyMMdd"));

        // 表名后缀
        String tableNameSuffix = TableConstants.buildTableNameSuffix(date, shardIndex);

        int batchSize = 1000;

        int processedTotal = 0;

        for (; ; ) {
            // 分批次查询
            List<Long> noteIds = selectRecordMapper.selectBatchFromDataAlignNoteCollectCountTempTable(tableNameSuffix, batchSize);

            if (CollUtil.isEmpty(noteIds)) break;

            noteIds.forEach(noteId -> {
                // 2.循环这一批发生变更的用户ID，对 t_note_collection 关注表执行 count(*) 操作，获取总数
                int collectCount = selectRecordMapper.selectCountFromNoteCollectTableByNoteId(noteId);

                // 3.更新 t_collect_count 表，并更新对应 Redis 缓存
                String countNoteKey = RedisKeyConstants.buildCountNoteKey(noteId);
                int count = updateRecordMapper.updateNoteCollectTotalByNoteId(noteId, collectCount);

                // 如果成功更新收藏总数
                if (count > 0) {
                    boolean hashKey = redisTemplate.hasKey(countNoteKey);

                    if (hashKey) {
                        // 更新 Redis 中缓存记录
                        redisTemplate.opsForHash().increment(countNoteKey, RedisKeyConstants.FIELD_COLLECT_TOTAL, collectCount);
                    }
                }
            });

            // 4.批量物理删除这一批次记录
            deleteMapper.batchDeleteDataAlignNoteCollectCountTempTable(tableNameSuffix, noteIds);

            // 当天已处理的记录数
            processedTotal += noteIds.size();

        }
        XxlJobHelper.log("================> 结束定时分片广播任务：对当日发生变更的笔记收藏数进行对齐，共对齐记录数：{}", processedTotal);
    }
}
